#ifndef SCHEDULER_H
#define SCHEDULER_H

#include "types.h"
#include "interval_tree.h"
#include <vector>
#include <map>
#include <memory>

/**
 * @class Scheduler
 * @brief 负责全局内存规划和调度的核心类。
 *
 * 该类接收内存访问序列，并根据一系列约束和优化目标，
 * 生成一个包含 Reload, Offload, Visit 和 Fin 操作的完整执行计划。
 */
class Scheduler
{
public:
    /**
     * @brief 构造函数。
     * @param m HBM总容量。
     * @param accesses 内存访问请求的完整列表。
     */
    Scheduler(long long m, const std::vector<Access> & accesses);

    /**
     * @brief 执行调度算法，生成最终的操作序列。
     */
    void run();

    /**
     * @brief 获取生成的调度结果。
     * @return const std::vector<Operation>& 操作序列。
     */
    const std::vector<Operation> & getResult() const;

private:
    // 内部状态
    unsigned long long memoryCapacity;
    /* long long memoryUsed; */
    /* std::set<std::shared_ptr<MemBlock> > memoryBlockSet; */
    IntervalTree memoryTree;
    /* IntervalTree loaded_memory;          // 当前HBM中的内存布局 */
    /* long long memory_bus_free_time = 0;  // 内存总线（用于Reload/Offload）下一次空闲的时刻 */
    /* long long last_task_finish_time = 0; // 上一个计算任务完成的时刻 */

    // 输入数据和预处理结果
    std::vector<Access> accessVec;
    unsigned long long currentTime;
    std::vector<std::shared_ptr<Task>> taskVec;
    /* std::map<long long, std::vector<int>> tasks; // 按start_time分组的任务，值为access的ID */
    /* std::map<int, int> next_use_map;             // 预计算的每个access的下一次使用时间（任务开始时间） */

    // 最终输出
    std::vector<Operation> resultOpVec;

    /**
     * @brief 将输入的访问序列按 start_time 分组为任务。
     */
    void groupAccessesIntoTasks();

    /**
     * @brief 预计算每个内存区间的下一次使用时间，用于卸载策略。
     * 这是一个启发式策略，对性能至关重要。
     */
    /* void computeNextUse(); */
    void prepareTask(
            std::shared_ptr<Task> & task,
            IntervalTree & taskMemoryTree);
    unsigned long long checkAndPrepareNextTask(
            long long unsigned startTime,
            std::shared_ptr<Task> & nextTask,
            IntervalTree & taskMemoryTree,
            long long unsigned maxTime);
    unsigned long long processTask(unsigned long long startTime, std::shared_ptr<Task> & task);

    /**
     * @brief 处理单个计算任务。
     * @param task_start_time 任务的标称开始时间。
     * @param access_ids 该任务包含的所有访问请求的ID。
     */
    /* void processTask(long long task_start_time, const std::vector<int> & access_ids); */

    /**
     * @brief 规划卸载操作以释放指定大小的内存。
     * @param size_to_free 需要释放的内存大小。
     * @param current_task_start_time 当前任务的开始时间，用于评估卸载优先级。
     */
    /* void planOffload(long long size_to_free, long long current_task_start_time); */

    /**
     * @brief 规划加载操作。
     * @param intervals_to_load 需要加载的内存区间列表。
     */
    /* void planReload(const std::vector<Interval> & intervals_to_load); */
};

#endif // SCHEDULER_H
